/**
 * 信息科技套件扩展模块
 * 
 * 版本历史：
    V1.2 新增修订 (20250427)
    1. 人体红外传感器模块修改 ：将人体红外传感器模块返回类型修改为 boolean 类型，方便进行逻辑判断。
    2. 光线传感器功能扩展 ：
   - 新增 LIGHT_SENSOR_VALUE_TYPE 枚举，包含 "强度值" 和 "勒克斯值" 两个选项。
   - 新增 readLightSensorWithType 函数，支持根据用户选择的类型读取光线传感器的值，选择 "强度值" 时生成 light.read() 代码，选择 "勒克斯值" 时生成 light.read()/409.5 代码。
    3. 字符串换行处理优化：
   - 改进displayTextWithWrap函数的换行逻辑，实现更智能的中英文混合换行处理
   - 添加字符宽度计算机制，区分中英文字符的显示宽度
   - 增加中文字符保护逻辑，避免中文字符被错误截断
  
  - V1.2 新增修订 (20250421)
  - - 本次修改人体红外传感器模块为boolean

  - V1.1 - 当前版本
  - - 新增MP3模块控制功能
  - * MP3模块初始化
  - * 播放指定歌曲
  - * 音量控制

  - V1.0 - 主要功能版本
  - - 新增数字传感器类型：倾斜传感器、触摸按键
  - - 完善引脚定义和菜单配置
  - - 优化代码结构和注释
  - - 新增功能模块：
  - * 字符串合并功能
  - * PWM输出控制模块（支持风扇、LED灯、电热丝）
  - * 防反插接口PWM输出控制
  - V0.2 - 根据V1.6.2 RC2.0修订
  - - 优化传感器读取精度
  - - 增加电机控制功能
  - V0.1 - 基础功能完成
  - - 添加温湿度传感器、光线传感器等基础传感器支持
  - - 实现屏幕显示、二维码生成等基础功能
 
 * 主要功能：
 * - 支持多种传感器读取（温湿度、光线、土壤湿度等）
 * - 支持数字传感器状态检测（按钮、红外、倾斜等）
 * - 支持屏幕显示控制（文字、图片、二维码）
 * - 支持电机/风扇控制
 * - 提供丰富的数学运算和逻辑比较功能
 * 
 * 版权所有 © 2025 斯帝姆(STEAM)科技
 */

enum SIZE {
    //% block="29*29"
    1,
    //% block="58*58"
    2
}

enum LINE {
    //% block="1"
    1,
    //% block="2"
    2,
    //% block="3"
    3,
    //% block="4"
    4
}

enum BTN {
    //% block="A"
    A,
    //% block="B"
    B,
    //% block="A+B"
    AB
}

// 首先修改COMPARE_OPERATOR枚举定义
enum COMPARE_OPERATOR {
    //% block="等于 =="
    EQUAL,
    //% block="不等于 !="
    NOT_EQUAL,
    //% block="大于 >"
    GREATER,
    //% block="大于等于 >="
    GREATER_EQUAL,
    //% block="小于 <"
    LESS,
    //% block="小于等于 <="
    LESS_EQUAL,
    //% block="与 &&"
    AND,
    //% block="或 ||"
    OR
}

enum KAIGUAN {
    //% block="开"
    HIGH,
    //% block="关"
    LOW
}

// 在枚举定义部分添加操作符枚举
enum CAOZUOFU {
    //% block="% 取余"
    MOD,
    //% block="+ 加"
    ADD,
    //% block="- 减"
    SUB,
    //% block="* 乘"
    MUL,
    //% block="/ 除"
    DIV,
    //% block="// 除取整"
    INT_DIV,
    //% block="& 与"
    AND,
    //% block="| 或"
    OR,
    //% block="^ 异或"
    XOR,
    //% block="<< 左移"
    LSHIFT,
    //% block=">> 右移"
    RSHIFT
}

// 修改BUILTIN_IMAGE枚举定义
enum BUILTIN_IMAGE {
    //% block="心形"
    0,
    //% block="高兴"
    1,
    //% block="笑脸"
    2,
    //% block="伤心"
    3,
    //% block="困惑"
    4,
    //% block="生气"
    5,
    //% block="睡着"
    6,
    //% block="惊讶"
    7,
    //% block="愚蠢"
    8,
    //% block="石头"
    9,
    //% block="剪刀"
    10,
    //% block="布"
    11
}

// 添加电机相关枚举
enum MOTOR_PORT {
    //% block="M1"
    M1,
    //% block="M2"
    M2,
    //% block="全部"
    ALL
}

enum MOTOR_DIRECTION {
    //% block="正转"
    CW,
    //% block="反转"
    CCW
}

// 在枚举定义部分添加换行选项枚举
enum WRAP_MODE {
    //% block="换行"
    WRAP,
    //% block="不换行"
    NOWRAP
}

// 在枚举定义部分添加气压传感器测量类型枚举
enum BME280_TYPE {
    //% block="气压(Pa)"
    PRESSURE,
    //% block="温度(℃)"
    TEMPERATURE,
    //% block="湿度(%rh)"
    HUMIDITY,
    //% block="海拔(m)"
    ALTITUDE
}

// 在枚举定义部分添加斯帝姆信息科技扩展板V1.0防反插引脚和读取类型枚举
enum STEAM_PIN {
    //% block="P2"
    P2,
    //% block="P3"
    P3,
    //% block="P13"
    P13,
    //% block="P14"
    P14,
    //% block="P15"
    P15
}

// 在枚举定义部分添加斯帝姆信息科技扩展板V1.0防反插引脚和读取类型枚举
//仅P2/P13/P14/P15支持数字传感器0、1输入值
enum STEAM_PIN_D {
    //% block="P2"
    P2,
    //% block="P13"
    P13,
    //% block="P14"
    P14,
    //% block="P15"
    P15
}
// 在枚举定义部分添加斯帝姆信息科技扩展板V1.0防反插引脚和读取类型枚举
//仅P13/P14/P15支持DHT11温湿度传感器
enum DHT_PIN {
    //% block="P13"
    P13,
    //% block="P14"
    P14,
    //% block="P15"
    P15
}
// 添加舵机引脚枚举
enum SERVO_PIN {
    //% block="P0"
    P0,
    //% block="P1"
    P1,
    //% block="P2"
    P2,
    //% block="P8"
    P8,
    //% block="P9"
    P9,
    //% block="P13"
    P13,
    //% block="P14"
    P14,
    //% block="P15"
    P15
}

//温湿度传感器使用的类型
enum DHT_TYPE {
    //% block="温度(℃)"
    TEMPERATURE,
    //% block="湿度(%rh)"
    HUMIDITY
}

// 在枚举定义部分添加数字传感器类型枚举
enum DIGITAL_SENSOR_TYPE {
    //% block="人体红外" 
    PIR,
    //% block="碰撞传感器"
    BUMPER,
    //% block="红外对射"
    IR_BEAM
    //% block="倾斜"
    //% block="倾斜"
    TILT,
    //% block="触摸按键"
    TOUCH_BUTTON,
    //% block="按钮"
    BUTTON
}

// 在枚举定义部分添加输出设备类型
enum OUTPUT_DEVICE_TYPE {
    //% block="风扇"
    FAN,
    //% block="LED灯"
    LED,
    //% block="电热丝"
    HEATER
}

// 在枚举定义部分添加MP3播放模式枚举
enum MP3_MODE {
    //% block="播放"
    PLAY,
    //% block="暂停播放"
    PAUSE,
    //% block="结束播放"
    STOP,
    //% block="音量加"
    VOLUME_UP,
    //% block="音量减"
    VOLUME_DOWN,
    //% block="上一曲"
    PREV,
    //% block="下一曲"
    NEXT
}

// 在枚举定义部分添加颜色调色板枚举
enum COLOR_PALETTE {
    //% block="红色"
    RED,
    //% block="绿色" 
    GREEN,
    //% block="蓝色"
    BLUE,
    //% block="黄色"
    YELLOW,
    //% block="紫色"
    PURPLE,
    //% block="青色"
    CYAN,
    //% block="白色"
    WHITE,
    //% block="黑色"
    BLACK
}

// 在枚举定义部分添加声音传感器值类型枚举
enum SOUND_SENSOR_VALUE_TYPE {
    //% block="强度值"
    INTENSITY,
    //% block="分贝值dB"
    DECIBEL
}

// 在枚举定义部分添加光线传感器值类型枚举
enum LIGHT_SENSOR_VALUE_TYPE {
    //% block="强度值"
    INTENSITY,
    //% block="勒克斯值lx"
    LUX
}


// 添加填充选项枚举
enum FILL_OPTION {
        //% block="实心填充"
        FILLED,
        //% block="空心边框"
        OUTLINE
}

// 在枚举定义部分添加语音识别模块识别模式枚举
enum SB_MODE {
    //% block="循环模式"
    LOOP,
    //% block="指令模式"
    PASSWORD,
    //% block="按钮模式"
    BUTTON
}

// 在枚举定义部分添加语音识别模块麦克风模式枚举
enum MIC_MODE {
    //% block="默认"
    MIC,
    //% block="外部音频"
    MONO
}


//颜色值"#AA278D"(紫色),"#0000EE"(纯蓝色)，浅蓝色 33CCFF
//% color="#208e20" iconWidth=30 iconHeight=30
namespace xxkjxk {

    //二级标签文字   Mind+1.8.0 RC3.0及以上版本新增功能
    //blockType为tag，block内容为显示的文字  函数名不能跟其他函数重名，函数内容留空即可。
    //% block="▶ 输入" blockType="tag"
    export function tag_input() {}

    //% block="读取声音传感器[ValueType]" blockType="reporter"
    //% ValueType.shadow="dropdown" ValueType.options="SOUND_SENSOR_VALUE_TYPE" ValueType.defl="SOUND_SENSOR_VALUE_TYPE.INTENSITY"
    export function readSoundSensor(parameter: any, block: any) {
        let valueType = parameter.ValueType.code;
        let code = "";

        if (valueType === "INTENSITY") {
            code = `sound.read()`;
        } else if (valueType === "DECIBEL") {
            code = `(sound.read()+83.2073) / 11.003`;
        }

        Generator.addCode(code);
    }


    //% block="读取光线传感器[ValueTypeGX]" blockType="reporter"
    //% ValueTypeGX.shadow="dropdown" ValueTypeGX.options="LIGHT_SENSOR_VALUE_TYPE" ValueTypeGX.defl="LIGHT_SENSOR_VALUE_TYPE.INTENSITY"
    export function readLightSensorWithType(parameter: any, block: any) {
        let valueType = parameter.ValueTypeGX.code;
        let code = "";

        if (valueType === "INTENSITY") {
            code = `light.read()`;
        } else if (valueType === "LUX") {
            code = `light.read()/409.5`;
        }

        Generator.addCode(code);
    }

    //% block="读取超声波传感器距离（cm）" blockType="reporter"
    export function getUltrasonicDistance(parameter: any, block: any) {
        Generator.addInclude('URM10', '#include <DFRobot_URM10.h>');
        Generator.addObject('csb10', 'DFRobot_URM10', 'csb10;');
        Generator.addCode(`csb10.getDistanceCM(P8, P9)`);
    }


    //% block="读取温湿度传感器[pin][duqutype]" blockType="reporter"
    //% pin.shadow="dropdown" pin.options="DHT_PIN" pin.defl="DHT_PIN.P13"
    //% duqutype.shadow="dropdown" duqutype.options="DHT_TYPE" duqutype.defl="DHT_TYPE.TEMPERATURE"
    export function readDHTValue(parameter: any, block: any) {
        let pin = parameter.pin.code;
        let type = parameter.duqutype.code;
        
        // 添加头文件和对象定义
        Generator.addInclude('DHT', '#include <DFRobot_DHT.h>');
        Generator.addObject(`dht11_${pin.toLowerCase()}`, 'DFRobot_DHT', `dht11_${pin.toLowerCase()};`);
        
        // 在setup中添加初始化代码
        Generator.addSetup(`dht11_${pin.toLowerCase()}.begin`, `dht11_${pin.toLowerCase()}.begin(${pin}, DHT11);`);
        
        // 根据类型返回不同的读取函数
        if (type === "TEMPERATURE") {
            Generator.addCode(`dht11_${pin.toLowerCase()}.getTemperature()`);
        } else {
            Generator.addCode(`dht11_${pin.toLowerCase()}.getHumidity()`);
        }
    }


    //% block="读取光线传感器值（外置)(范围0-4095）[pin]" blockType="reporter"
    //% pin.shadow="dropdown" pin.options="STEAM_PIN" pin.defl="DHT_PIN.P2"
    export function readLightSensor(parameter: any, block: any) {
        let pin = parameter.pin.code;
        Generator.addCode(`analogRead(${pin})`);
    }

    //% block="读取土壤湿度传感器值[pin]" blockType="reporter"
    //% pin.shadow="dropdown" pin.options="STEAM_PIN" pin.defl="DHT_PIN.P2"
    export function readSoilMoisture(parameter: any, block: any) {
        let pin = parameter.pin.code;
        Generator.addCode(`analogRead(${pin})`);
    }


    //% block="读取[TTYPE]传感器状态(值为0/1)[pin]" blockType="boolean"
    //% pin.shadow="dropdown" pin.options="STEAM_PIN_D" pin.defl="DHT_PIN.P2"
    //% TTYPE.shadow="dropdown" TTYPE.options="DIGITAL_SENSOR_TYPE" TTYPE.defl="DIGITAL_SENSOR_TYPE.BUTTON"
    export function readDigitalSensor(parameter: any, block: any) {
        let pin = parameter.pin.code;
        Generator.addCode(`digitalRead(${pin})`);
    }

    //--------------------------------------------------------------
    //block="---" ，固定格式，block内容为三个-，无需blockType参数
    //% block="---"
    export function noteSepASR() {}
    //二级标签文字   Mind+1.8.0 RC3.0及以上版本新增功能
    //% block="语音识别模块初始化 识别模式为[SBMode] 麦克风模式为[MKFMode] I2C地址为0x4F" blockType="command"
    //% SBMode.shadow="dropdown" SBMode.options="SB_MODE" SBMode.defl="SB_MODE.BUTTON"
    //% MKFMode.shadow="dropdown" MKFMode.options="MIC_MODE" MKFMode.defl="MIC_MODE.MIC"
    export function initVoiceRecognition(parameter: any, block: any) {
        let sbMode = parameter.SBMode.code;
        let micMode = parameter.MKFMode.code;
        Generator.addInclude('asr', '#include <DFRobot_ASR_M.h>');
        Generator.addObject('asr', 'DFRobot_ASR', 'asr2;');
        
        // 将枚举值转换为对应的常量
        let sbModeStr = '';
        switch(sbMode) {
            case "LOOP":
                sbModeStr = "LOOP";
                break;
            case "PASSWORD":
                sbModeStr = "PASSWORD";
                break;
            case "BUTTON":
                sbModeStr = "BUTTON";
                break;
            default:
                sbModeStr = "BUTTON";
        }
        
        let micModeStr = '';
        switch(micMode) {
            case "MIC":
                micModeStr = "MIC";
                break;
            case "MONO":
                micModeStr = "MONO";
                break;
            default:
                micModeStr = "MIC";
        }
        
        Generator.addSetup('asr2.begin', `asr2.begin(${sbModeStr}, ${micModeStr});`);
    }

    //% block="添加关键词[KEY]编号为[NUM]" blockType="command"
    //% KEY.shadow="string" KEY.defl="kai deng"
    //% NUM.shadow="number" NUM.defl=1
    export function addVoiceKeyword(parameter: any, block: any) {
        let key = parameter.KEY.code;
        let num = parameter.NUM.code;
        Generator.addInclude('asr', '#include <DFRobot_ASR_M.h>');
        Generator.addSetup('asr2.addCommand',`asr2.addCommand(${key}, ${num});`);
    }
    
    //% block="设置完成 开始识别" blockType="command"
    export function startVoiceRecognition(parameter: any, block: any) {
        Generator.addInclude('asr', '#include <DFRobot_ASR_M.h>');
        Generator.addSetup('asr2.start', 'asr2.start();');
    }
    
    //% block="识别一次语音，获取编号" blockType="reporter"
    export function readVoiceCommand(parameter: any, block: any) {
        Generator.addInclude('asr', '#include <DFRobot_ASR_M.h>');
        Generator.addCode(`asr2.read()`);
    }
    
    //% block="识别一次语音，如果获得的编号等于[asr_num]" blockType="boolean"
    //% asr_num.shadow="number" asr_num.defl=1 
    export function isVoiceCommandEqual(parameter: any, block: any) {
        let num = parameter.asr_num.code;
        Generator.addInclude('asr', '#include <DFRobot_ASR_M.h>');
        Generator.addCode(`asr2.read()==${num}`);
    }

    
    //--------------------------------------------------------------
    //block="---" ，固定格式，block内容为三个-，无需blockType参数
    //% block="---"
    export function noteSep02() {}
    //二级标签文字   Mind+1.8.0 RC3.0及以上版本新增功能
    //blockType为tag，block内容为显示的文字  函数名不能跟其他函数重名，函数内容留空即可。
    //% block="▶ 计算" blockType="tag"
    export function tag_program() {}


   //% color="#AA00BB" 
    //% block="[A][operatesy][B]" blockType="reporter"
    //% A.shadow="number" A.defl=1
    //% operatesy.shadow="dropdown" operatesy.options="CAOZUOFU" operatesy.defl=CAOZUOFU.MOD
    //% B.shadow="number" B.defl=3
    export function operate(parameter: any, block: any) {
        let a = parameter.A.code;
        let b = parameter.B.code;
        let operator = parameter.operatesy.code;
        let operatorSymbol: string;

        switch(operator) {
            case "MOD":
                operatorSymbol = "%";
                break;
            case "ADD":
                operatorSymbol = "+";
                break;
            case "SUB":
                operatorSymbol = "-";
                break;
            case "MUL":
                operatorSymbol = "*";
                break;
            case "DIV":
                operatorSymbol = "/";
                break;
            case "INT_DIV":
                operatorSymbol = "//";
                Generator.addCode(`(int)(${a} ${operatorSymbol} ${b})`);
                return;
            case "AND":
                operatorSymbol = "&";
                break;
            case "OR":
                operatorSymbol = "|";
                break;
            case "XOR":
                operatorSymbol = "^";
                break;
            case "LSHIFT":
                operatorSymbol = "<<";
                break;
            case "RSHIFT":
                operatorSymbol = ">>";
                break;
            default:
                operatorSymbol = "%";
        }

        Generator.addCode(`(${a} ${operatorSymbol} ${b})`);
    }



    //% block="[A] [OP] [B]" blockType="boolean"
    //% A.shadow="number" A.defl=0
    //% OP.shadow="dropdown" OP.options="COMPARE_OPERATOR" OP.defl="COMPARE_OPERATOR.EQUAL"
    //% B.shadow="number" B.defl=0
    export function compare(parameter: any, block: any) {
        let a = parameter.A.code;
        let b = parameter.B.code;
        let op = parameter.OP.code;
        let operatorSymbol: string;

        switch(op) {
            case "GREATER":
                operatorSymbol = ">";
                break;
            case "GREATER_EQUAL":
                operatorSymbol = ">=";
                break;
            case "EQUAL":
                operatorSymbol = "==";
                break;
            case "LESS":
                operatorSymbol = "<";
                break;
            case "LESS_EQUAL":
                operatorSymbol = "<=";
                break;
            case "NOT_EQUAL":
                operatorSymbol = "!=";
                break;
            default:
                operatorSymbol = "==";
        }

        Generator.addCode([`(${a} ${operatorSymbol} ${b})`, Generator.ORDER_RELATIONAL]);
    }



    function replace(str: string) {
        return str.replace("+", "");
    }


    //% block="映射[value] 从[fromLow]-[fromHigh] 到[toLow]-[toHigh]" blockType="reporter"
    //% value.shadow="number" value.defl=666
    //% fromLow.shadow="number" fromLow.defl=0
    //% fromHigh.shadow="number" fromHigh.defl=1023
    //% toLow.shadow="number" toLow.defl=0
    //% toHigh.shadow="number" toHigh.defl=255
    export function mapValue(parameter: any, block: any) {
        let value = parameter.value.code;
        let fromLow = parameter.fromLow.code;
        let fromHigh = parameter.fromHigh.code;
        let toLow = parameter.toLow.code;
        let toHigh = parameter.toHigh.code;
        
        Generator.addCode(`map(${value}, ${fromLow}, ${fromHigh}, ${toLow}, ${toHigh})`);
    }

    //% block="合并[STR1][STR2][STR3]" blockType="reporter"
    //% STR1.shadow="string" STR1.defl="物"
    //% STR2.shadow="string" STR2.defl="联"
    //% STR3.shadow="string" STR3.defl="网"
    export function concatStrings(parameter: any, block: any) {
        let str1 = parameter.STR1.code;
        let str2 = parameter.STR2.code;
        let str3 = parameter.STR3.code;
        Generator.addCode(`(String(${str1}) + String(${str2})+ String(${str3}))`);
    }

    
    //block="---" ，固定格式，block内容为三个-，无需blockType参数
    //% block="---"
    export function noteSep03() {}
    //二级标签文字   Mind+1.8.0 RC3.0及以上版本新增功能
    //blockType为tag，block内容为显示的文字  函数名不能跟其他函数重名，函数内容留空即可。
    //% block="▶ 输出" blockType="tag"
    export function tag_output() {}


    //% block="在坐标x[X] y[Y]显示二维码[STR] 大小[SIZE] " blockType="command"
    //% STR.shadow="string" STR.defl="http://www.wearemaker.cn"
    //% X.shadow="range" X.params.min=0 X.params.max=127 X.defl=0
    //% Y.shadow="range" Y.params.min=0 Y.params.max=63 Y.defl=0
    //% SIZE.shadow="dropdownRound" SIZE.options="SIZE" SIZE.defl="SIZE.2"
    export function qrcode(parameter: any, block: any) {
        let str = parameter.STR.code
        let x = parameter.X.code
        let y = parameter.Y.code
        let size = parameter.SIZE.code
        Generator.addInclude('oled12864', '#include <oled12864.h>');
        Generator.addObject(`myoled`, `OLED_12864`, `myoled;`);
        Generator.addSetup(`myoled.begin`, `myoled.begin();`);
        Generator.addCode(`myoled.qrcode(${x}, ${y}, ${str}, ${size});`);
    }


//% block="屏幕显示文字[STR]在第[LINE]行[WRAP]" blockType="command"
//% STR.shadow="string" STR.defl="请输入文字"
//% LINE.shadow="dropdownRound" LINE.options="LINE" LINE.defl="LINE.1"
//% WRAP.shadow="dropdown" WRAP.options="WRAP_MODE" WRAP.defl="WRAP_MODE.WRAP"
export function displayTextWithWrap(parameter: any, block: any) {
    let str = parameter.STR.code;
    let line = parameter.LINE.code;
    let wrapMode = parameter.WRAP.code;
    
    Generator.addInclude('MPython', '#include <MPython.h>');
    // 定义文本显示相关变量
    Generator.addObject(`val1`, `String`, `text;`);
    Generator.addObject(`val2`, `int`, `lineNum;`);
    Generator.addObject(`val3`, `int`, `maxLen`);
    Generator.addObject(`val4`, `int`, `startPos`);
    Generator.addSetupMainTop("mPython.begin", "mPython.begin();");
    
    if (wrapMode == "WRAP") {
        // 自动换行处理逻辑 - 优化中英文混合的换行处理
        Generator.addCode(`
    text = String(${str});
    lineNum = ${line};
    startPos = 0;
    
    while(startPos < text.length()) {
        display.setCursorLine(lineNum++);
        int endPos = startPos;
        int charCount = 0;
        int widthCount = 0;
        
        // 计算当前行可以显示的字符数，考虑中英文混合情况
        // 假设中文字符宽度为2，英文字符宽度为1
        while(endPos < text.length() && charCount < 16) { // 每行最多显示约16个宽度单位
            char c = text.charAt(endPos);
            if(c < 0x80) {
                // 英文字符，宽度为1
                widthCount += 1;
            } else {
                // 中文字符（UTF-8编码通常为3字节），宽度为2
                widthCount += 2;
                // 确保不截断中文字符
                if(endPos + 2 < text.length()) {
                    endPos += 2; // 跳过UTF-8中文字符的后续字节
                }
            }
            endPos++;
            charCount++;
            
            // 如果宽度超过阈值，结束当前行
            if(widthCount >= 16) break;
        }
        
        // 确保不会超过文本总长度
        endPos = min(endPos, text.length());
        String lineText = text.substring(startPos, endPos);
        display.printLine(lineText);
        startPos = endPos;

        // 最多显示4行
        if(lineNum > 4) break;
    }
            `);
    } else {
        // 不换行处理
        Generator.addCode(`
display.setCursorLine(${line});
display.printLine(${str});
            `);
    }
}

  
    //% block="OLED屏幕显示内置图片[IMAGE]在坐标x:[X] y:[Y]大小[SIZE]" blockType="command"
    //% IMAGE.shadow="dropdown" IMAGE.options="BUILTIN_IMAGE" IMAGE.defl="BUILTIN_IMAGE.HEART"
    //% X.shadow="range" X.params.min=0 X.params.max=127 X.defl=0
    //% Y.shadow="range" Y.params.min=0 Y.params.max=63 Y.defl=0
    //% SIZE.shadow="dropdownRound" SIZE.options="SIZE" SIZE.defl="SIZE.2"
    export function oledShowBuiltinImage(parameter: any, block: any) {
        let image = parameter.IMAGE.code;
        let x = parameter.X.code;
        let y = parameter.Y.code;
        let size = parameter.SIZE.code;
        
        // 根据SIZE值设置对应的宽度和高度
        let width = 0;
        let height = 0;
        
        if (size === "1") {
            width = 25;
            height = 25;
        } else if (size === "2") {
            width = 50;
            height = 50;
        } else if (size === "3") {
            width = 75;
            height = 37; // 保持比例，避免超出屏幕高度
        } else if (size === "4") {
            width = 100;
            height = 50;
        } else {
            width = 50; // 默认值
            height = 50;
        }
        
        Generator.addInclude('oled12864', '#include <oled12864.h>');
        Generator.addObject(`myoled`, `OLED_12864`, `myoled;`);
        Generator.addSetup(`myoled.begin`, `myoled.begin();`);
        
        // 生成调用OLED_12864库内置图片函数的代码
        Generator.addCode(`myoled.showBuiltinImage(${x}, ${y}, ${image}, ${width}, ${height});`);
    }
    


    //% block="OLED屏幕绘制矩形x:[X] y:[Y] 宽:[WIDTH] 高:[HEIGHT] 样式:[FILL]" blockType="command"
    //% X.shadow="range" X.params.min=0 X.params.max=127 X.defl=10
    //% Y.shadow="range" Y.params.min=0 Y.params.max=63 Y.defl=10
    //% WIDTH.shadow="range" WIDTH.params.min=1 WIDTH.params.max=128 WIDTH.defl=30
    //% HEIGHT.shadow="range" HEIGHT.params.min=1 HEIGHT.params.max=64 HEIGHT.defl=20
    //% FILL.shadow="dropdown" FILL.options="FILL_OPTION" FILL.defl="FILL_OPTION.FILLED"
    export function drawRect(parameter: any, block: any) {
        let x = parameter.X.code;
        let y = parameter.Y.code;
        let width = parameter.WIDTH.code;
        let height = parameter.HEIGHT.code;
        let fillOption = parameter.FILL.code;
        let fill = fillOption === "FILLED" ? "true" : "false";
        
        Generator.addInclude('oled12864', '#include <oled12864.h>');
        Generator.addObject(`myoled`, `OLED_12864`, `myoled;`);
        Generator.addSetup(`myoled.begin`, `myoled.begin();`);
        Generator.addSetup(`myoled.setBrushColor`, `myoled.setBrushColor(1); // 设置画笔颜色为黑色`);
        
        Generator.addCode(`myoled.rect(${x}, ${y}, ${width}, ${height}, ${fill});`);
    }
    
    //% block="OLED屏幕绘制圆形 中心x:[X] y:[Y] 半径:[RADIUS] 样式:[FILL]" blockType="command"
    //% X.shadow="range" X.params.min=0 X.params.max=127 X.defl=64
    //% Y.shadow="range" Y.params.min=0 Y.params.max=63 Y.defl=32
    //% RADIUS.shadow="range" RADIUS.params.min=1 RADIUS.params.max=32 RADIUS.defl=15
    //% FILL.shadow="dropdown" FILL.options="FILL_OPTION" FILL.defl="FILL_OPTION.FILLED"
    export function drawCircleBlock(parameter: any, block: any) {
        let x = parameter.X.code;
        let y = parameter.Y.code;
        let radius = parameter.RADIUS.code;
        let fillOption = parameter.FILL.code;
        let fill = fillOption === "FILLED" ? "true" : "false";
        
        Generator.addInclude('oled12864', '#include <oled12864.h>');
        Generator.addObject(`myoled`, `OLED_12864`, `myoled;`);
        Generator.addSetup(`myoled.begin`, `myoled.begin();`);
        Generator.addSetup(`myoled.setBrushColor`, `myoled.setBrushColor(1); // 设置画笔颜色为黑色`);
        
        Generator.addCode(`myoled.drawCircle(${x}, ${y}, ${radius}, ${fill});`);
    }
    
    //% block="OLED屏幕清除" blockType="command"
    export function clearOLED(parameter: any, block: any) {
        Generator.addInclude('oled12864', '#include <oled12864.h>');
        Generator.addObject(`myoled`, `OLED_12864`, `myoled;`);
        Generator.addSetup(`myoled.begin`, `myoled.begin();`);
        
        Generator.addCode(`myoled.clear();`);
    }
    
    //% block="屏幕显示内置图片[IMAGE]在坐标x:[X] y:[Y]" blockType="command"
    //% IMAGE.shadow="dropdown" IMAGE.options="BUILTIN_IMAGE" IMAGE.defl="BUILTIN_IMAGE.HEART"
    //% X.shadow="range" X.params.min=0 X.params.max=127 X.defl=0
    //% Y.shadow="range" Y.params.min=0 Y.params.max=63 Y.defl=0
    export function showBuiltinImage(parameter: any, block: any) {
        let image = parameter.IMAGE.code;
        let x = parameter.X.code;
        let y = parameter.Y.code;
        
        Generator.addInclude('MPython', '#include <MPython.h>');
        Generator.addInclude('images', '#include <images.h>');
        Generator.addSetupMainTop("mPython.begin", "mPython.begin();");
        
        Generator.addCode(`
            // 定义目标数组并初始化为0
            uint8_t imageData[1][350] = {0};
            
            // 根据选择复制数据
            switch(${image}) {
                case 0: memcpy(imageData, HEART, sizeof(HEART)); break;
                case 1: memcpy(imageData, HAPPY, sizeof(HAPPY)); break;
                case 2: memcpy(imageData, SMILE, sizeof(SMILE)); break;
                case 3: memcpy(imageData, SAD, sizeof(SAD)); break;
                case 4: memcpy(imageData, CONFUSED, sizeof(CONFUSED)); break;
                case 5: memcpy(imageData, ANGRY, sizeof(ANGRY)); break;
                case 6: memcpy(imageData, ASLEEP, sizeof(ASLEEP)); break;
                case 7: memcpy(imageData, SURPRISED, sizeof(SURPRISED)); break;
                case 8: memcpy(imageData, SILLY, sizeof(SILLY)); break;
                case 9: memcpy(imageData, ROCK, sizeof(ROCK)); break;
                case 10: memcpy(imageData, SCISSORS, sizeof(SCISSORS)); break;
                case 11: memcpy(imageData, PAPER, sizeof(PAPER)); break;
                default: memcpy(imageData, HEART, sizeof(HEART));
            }
            
            // 显示图片
            display.drawImage(${x}, ${y}, 50, 50, imageData[0]);
        `);
    }

   //% block="电机(风扇/马达/水泵)[PORT]以[SPEED]速度[DIR]" blockType="command"
    //% PORT.shadow="dropdown" PORT.options="MOTOR_PORT" PORT.defl="MOTOR_PORT.M1"
    //% SPEED.shadow="range" SPEED.params.min=0 SPEED.params.max=255 SPEED.defl=200
    //% DIR.shadow="dropdown" DIR.options="MOTOR_DIRECTION" DIR.defl="MOTOR_DIRECTION.CW"
    export function motorControl(parameter: any, block: any) {
        let port = parameter.PORT.code;
        let speed = parameter.SPEED.code;
        let direction = parameter.DIR.code;
        
        Generator.addInclude('motor', '#include <IOBOX_Motor.h>');
        Generator.addObject('motor_ib', 'IOBOX_Motor', 'motor_ib;');
        Generator.addCode(`motor_ib.motorRun(motor_ib.${port}, motor_ib.${direction}, ${speed});`);
    }

    //% block="电机(风扇/马达/水泵)[PORT]停止" blockType="command"
    //% PORT.shadow="dropdown" PORT.options="MOTOR_PORT" PORT.defl="MOTOR_PORT.M1"
    export function motorStop(parameter: any, block: any) {
        let port = parameter.PORT.code;
        
        Generator.addInclude('motor', '#include <IOBOX_Motor.h>');
        Generator.addObject('motor_ib', 'IOBOX_Motor', 'motor_ib;');
        Generator.addCode(`motor_ib.motorStop(motor_ib.${port});`);
    }

    //% block="设置[TType]扩展板防反插接口[PIN]输出WM[Val]" blockType="command"
    //% PIN.shadow="dropdown" PIN.options="DHT_PIN" PIN.defl="DHT_PIN.P13"
    //% TType.shadow="dropdown" TType.options="OUTPUT_DEVICE_TYPE" TType.defl="OUTPUT_DEVICE_TYPE.FAN"
    //% Val.shadow="range" Val.params.min=0 Val.params.max=1023 Val.defl=0
    export function setAnalogOutput(parameter: any, block: any) {
        let pin = parameter.PIN.code;
        let val = parameter.Val.code;
        Generator.addCode(`analogWrite(${pin}, ${val});`);
    }


    //block="---" ，固定格式，block内容为三个-，无需blockType参数
    //% block="---"
    export function noteSep_Servo() {}

    //% block="读取舵机[DPin]当前角度" blockType="reporter"
    //% DPin.shadow="dropdown" DPin.options="SERVO_PIN" DPin.defl="SERVO_PIN.P13"
    export function readServoAngle(parameter: any, block: any) {
        let dPin = parameter.DPin.code;
        Generator.addInclude('servo', '#include <Steam_Servo.h>');
        Generator.addObject(`steamServo_${dPin}`, 'Servo', `steamServo_${dPin};`);
        Generator.addSetup(`steamServo_${dPin}.attach`, `steamServo_${dPin}.attach(${dPin});`);
        Generator.addCode(`steamServo_${dPin}.read()`);
    }

    //% block="设置舵机引脚[DPin]为[Angle]度" blockType="command"
    //% DPin.shadow="dropdown" DPin.options="SERVO_PIN" DPin.defl="SERVO_PIN.P13"
    //% Angle.shadow="angle" Angle.params.min=0 Angle.params.max=180 Angle.defl=0
    export function setServoAngle(parameter: any, block: any) {
        let dPin = parameter.DPin.code;
        let angle = parameter.Angle.code;
        
        Generator.addInclude('servo', '#include <Steam_Servo.h>');
        Generator.addObject(`steamServo_${dPin}`, 'Servo', `steamServo_${dPin};`);
        Generator.addSetup(`steamServo_${dPin}.attach`, `steamServo_${dPin}.attach(${dPin});`);
        
        Generator.addCode(`steamServo_${dPin}.angle(abs(${angle}));`);
    }

    //block="---" ，固定格式，block内容为三个-，无需blockType参数
    //% block="---"
    export function noteSep_rfid() {}
    //二级标签文字   Mind+1.8.0 RC3.0及以上版本新增功能
    //% block="初始化RFID/NFC模块I2C接口" blockType="command"
    export function initRFIDModule(parameter: any, block: any) {
        Generator.addInclude('nfc', '#include <DFRobot_NFC0231.h>');
        Generator.addObject('rfid532', 'DFRobot_PN532_IIC', 'rfid532;');
        Generator.addSetup('rfid532.begin', 'rfid532.begin();');
    }

    //% block="检测到卡片？" blockType="boolean"
    export function isRFIDCardDetected(parameter: any, block: any) {
            Generator.addInclude('nfc', '#include <Steam_RFID.h>');
            Generator.addCode('rfid532.scan()');
    }

    //% block="读取RFID卡信息" blockType="reporter"
export function readRFIDCard(parameter: any, block: any) {
        Generator.addInclude('nfc', '#include <Steam_RFID.h>');
        Generator.addCode('rfid532.readUid()');
    }

    //block="---" ，固定格式，block内容为三个-，无需blockType参数
    //% block="---"
    export function noteSep_magnetometer() {}
    //二级标签文字   Mind+1.8.0 RC3.0及以上版本新增功能
    //% block="初始化地磁传感器" blockType="command"
    export function initMagnetometer(parameter: any, block: any) {
        Generator.addInclude('magnetometer', '#include "MMC5983MA.h"');
        Generator.addObject('mmc', 'MMC5983MA', 'mmc;');
        Generator.addSetup('mmc.begin', 'mmc.begin();');
        Generator.addSetup('mmc.cal();');
    }

    //% block="校准指南针" blockType="command"
    export function calibrateCompass(parameter: any, block: any) {
        Generator.addInclude('magnetometer', '#include "MMC5983MA.h"');
        Generator.addSetup('mmc.cal();');
    }

    //% block="去除当前磁场环境" blockType="command"
    export function removeMagneticField(parameter: any, block: any) {
        Generator.addInclude('magnetometer', '#include "MMC5983MA.h"');
        Generator.addCode('mmc.peeling();');
    }

    //% block="指南针方向" blockType="reporter"
    export function getCompassHeading(parameter: any, block: any) {
        Generator.addInclude('magnetometer', '#include "MMC5983MA.h"');
        Generator.addCode('mmc.get_heading()');
    }

    //block="---" ，固定格式，block内容为三个-，无需blockType参数
    //% block="---"
    export function noteSep_mp3() {}
    //二级标签文字   Mind+1.8.0 RC3.0及以上版本新增功能
    //% block="初始化MP3模块（扩展板防反插接口）" blockType="command"
    export function initMP3Module(parameter: any, block: any) {
        Generator.addInclude('mp3', '#include <DFRobot_SerialMp3.h>');
        Generator.addObject('steamMP3', 'DFRobot_SerialMp3', 'steamMP3;');
        Generator.addSetup('mp3.begin', 'steamMP3.begin(&Serial1, P0, P1);');
    }
    
    //% block="MP3的音量设为[VOLUME]%" blockType="command"
    //% VOLUME.shadow="range" VOLUME.params.min=0 VOLUME.params.max=100 VOLUME.defl=50
    export function setMP3Volume(parameter: any, block: any) {
        let volume = parameter.VOLUME.code;
        Generator.addInclude('mp3', '#include <DFRobot_SerialMp3.h>');
        Generator.addObject('steamMP3', 'DFRobot_SerialMp3', 'steamMP3;');
        Generator.addCode(`steamMP3.volume(${volume});`);
    }

    //% block="MP3模块的播放模式设为[MODE]" blockType="command"
    //% MODE.shadow="dropdown" MODE.options="MP3_MODE" MODE.defl="MP3_MODE.PLAY"
    export function setMP3Mode(parameter: any, block: any) {
        let mode = parameter.MODE.code;
        Generator.addInclude('mp3', '#include <DFRobot_SerialMp3.h>');
        Generator.addObject('steamMP3', 'DFRobot_SerialMp3', 'steamMP3;');
        
        switch(mode) {
            case "PLAY":
                Generator.addCode('steamMP3.play();');
                break;
            case "PAUSE":
                Generator.addCode('steamMP3.pause();');
                break;
            case "STOP":
                Generator.addCode('steamMP3.end();');
                break;
            case "VOLUME_UP":
                Generator.addCode('steamMP3.volumeUp();');
                break;
            case "VOLUME_DOWN":
                Generator.addCode('steamMP3.volumeDown();');
                break;
            case "PREV":
                Generator.addCode('steamMP3.prev();');
                break;
            case "NEXT":
                Generator.addCode('steamMP3.next();');
                break;
            default:
                Generator.addCode('steamMP3.play();');
        }
    }

    //% block="MP3模块播放第[NUM]首歌曲" blockType="command"
    //% NUM.shadow="number" NUM.defl=1
    export function playMP3Song(parameter: any, block: any) {
        let num = parameter.NUM.code;
        Generator.addInclude('mp3', '#include <DFRobot_SerialMp3.h>');
        Generator.addObject('steamMP3', 'DFRobot_SerialMp3', 'steamMP3;');
        Generator.addCode(`steamMP3.playList(${num});`);
    }



    //block="---" ，固定格式，block内容为三个-，无需blockType参数
    //% block="---"
    export function noteSep_rgb() {}

    //% block="RGB灯引脚[PIN]初始化，灯总数[NUM]" blockType="command"
    //% PIN.shadow="dropdown" PIN.options="DHT_PIN" PIN.defl="DHT_PIN.P13"
    //% NUM.shadow="number" NUM.defl=15
    export function initRGBLed(parameter: any, block: any) {
        let pin = parameter.PIN.code;
        let num = parameter.NUM.code;
        Generator.addInclude('neopixel', '#include <DFRobot_NeoPixel.h>');
        Generator.addObject(`rgb_${pin}`, 'DFRobot_NeoPixel', `rgb_${pin};`);
        // 修改此处，将 pin 和 num 传入 begin 方法
        Generator.addSetup(`rgb_${pin}.begin`, `rgb_${pin}.begin(${pin}, ${num});`);
    }

    //% block="RGB灯引脚[PIN]设置亮度为[BRIGHTNESS]" blockType="command"
    //% PIN.shadow="dropdown" PIN.options="DHT_PIN" PIN.defl="DHT_PIN.P13"
    //% BRIGHTNESS.shadow="range" BRIGHTNESS.params.min=0 BRIGHTNESS.params.max=255 BRIGHTNESS.defl=100
    export function setRGBBrightness(parameter: any, block: any) {
        let pin = parameter.PIN.code;
        let brightness = parameter.BRIGHTNESS.code;
        Generator.addCode(`rgb_${pin}.setBrightness(${brightness});`);
    }

    //% block="RGB灯引脚[PIN]全部熄灭" blockType="command"
    //% PIN.shadow="dropdown" PIN.options="DHT_PIN" PIN.defl="DHT_PIN.P13"
    export function clearRGBLed(parameter: any, block: any) {
        let pin = parameter.PIN.code;
        Generator.addCode(`rgb_${pin}.clear(); rgb_${pin}.show();`);
    }

    //% block="RGB灯引脚[PIN]灯号[START]-[END]显示颜色[COLOR]" blockType="command"
    //% PIN.shadow="dropdown" PIN.options="DHT_PIN" PIN.defl="DHT_PIN.P13"
    //% START.shadow="number" START.defl=0
    //% END.shadow="number" END.defl=15
    //% COLOR.shadow="dropdown" COLOR.options="COLOR_PALETTE" COLOR.defl="COLOR_PALETTE.RED"
    export function setRGBColor(parameter: any, block: any) {
        let pin = parameter.PIN.code;
        let start = parameter.START.code;
        let end = parameter.END.code;
        let color = parameter.COLOR.code;
        
        let colorCode = '';
        switch(color) {
            case "RED":
                colorCode = `rgb_${pin}.Color(255, 0, 0)`;
                break;
            case "GREEN":
                colorCode = `rgb_${pin}.Color(0, 255, 0)`;
                break;
            case "BLUE":
                colorCode = `rgb_${pin}.Color(0, 0, 255)`;
                break;
            case "YELLOW":
                colorCode = `rgb_${pin}.Color(255, 255, 0)`;
                break;
            case "PURPLE":
                colorCode = `rgb_${pin}.Color(255, 0, 255)`;
                break;
            case "CYAN":
                colorCode = `rgb_${pin}.Color(0, 255, 255)`;
                break;
            case "WHITE":
                colorCode = `rgb_${pin}.Color(255, 255, 255)`;
                break;
            default:
                colorCode = `rgb_${pin}.Color(0, 0, 0)`;
        }
        
        Generator.addCode(`
for(int i = ${start}; i <= ${end}; i++) {
    rgb_${pin}.setPixelColor(i, ${colorCode});
}
rgb_${pin}.show();`);
    }

    //% block="RGB灯引脚[PIN]灯号[LED]显示红[R]绿[G]蓝[B]" blockType="command"
    //% PIN.shadow="dropdown" PIN.options="DHT_PIN" PIN.defl="DHT_PIN.P13"
    //% LED.shadow="number" LED.defl=0
    //% R.shadow="range" R.params.min=0 R.params.max=255 R.defl=255
    //% G.shadow="range" G.params.min=0 G.params.max=255 G.defl=0
    //% B.shadow="range" B.params.min=0 B.params.max=255 B.defl=0
    export function setRGBColorCustom(parameter: any, block: any) {
        let pin = parameter.PIN.code;
        let led = parameter.LED.code;
        let r = parameter.R.code;
        let g = parameter.G.code;
        let b = parameter.B.code;
        
        Generator.addCode(`
rgb_${pin}.setPixelColor(${led}, rgb_${pin}.Color(${r}, ${g}, ${b}));
rgb_${pin}.show();`);
    }




}  //end-namespace xxkj
